package com.zuilapsa.jmc;

import java.io.*;
import java.util.*;

import org.dom4j.*;
import org.dom4j.io.*;

import com.zuilapsa.jmc.exporters.*;
import com.zuilapsa.jmc.userInterfaces.*;

public class Configuration {
	public static final String CONFIG_FILE = "/conf/jmc.configuration.xml";

	public static final String DEFINITION_FILE = "/opt/zues/etc/jmc.definition.xml";

	public static final int TELNET_PORT = 3023;

	public static final int XMLRPC_PORT = 3081;

	public static Configuration configuration = null;

	public Document definitionDoc;

	public Document configDoc;

	public static int getTelnetPort() {
		return TELNET_PORT;
	}

	protected Configuration() throws JmcException {
		loadDefinition();
		loadManagedConfig();
	}

	public static Configuration getInstance() throws JmcException {
		if (configuration == null)
			configuration = new Configuration();
		return configuration;
	}


	public boolean isGlob(Element definition) {
		return definition.attributeValue("name").contains("{*}");
	}

	public boolean isProperty(Element element) {
		return element.getName().equals("property");
	}

	public boolean isLevel(Element element) {
		return element.getName().equals("level");
	}


	public Element getRootConfigElement() {
		return configDoc.getRootElement();
	}

	public Element getRootDefinitionElement() {
		return definitionDoc.getRootElement();
	}


	public void loadManagedConfig() throws JmcException {
		try {
			SAXReader reader = new SAXReader();
			configDoc = reader.read(CONFIG_FILE);
		} catch (DocumentException e) {
			System.err.println(Thread.currentThread().getName()
					+ ": Error reading the configuration file");
			throw new JmcException("Error reading the configuration file", e);
		}
	}

	public void loadDefinition() throws JmcException {
		try {
			SAXReader reader = new SAXReader();
			definitionDoc = reader.read(DEFINITION_FILE);
		} catch (DocumentException e) {
			System.err.println(Thread.currentThread().getName()
					+ ": Error reading the definition file");
			throw new JmcException("Error reading the definition file", e);
		}
	}

	public void saveManagedConfig() throws JmcException {
		try {
			OutputFormat format = OutputFormat.createPrettyPrint();
			XMLWriter writer = new XMLWriter(new FileWriter(CONFIG_FILE),
					format);
			writer.write(configDoc);
			writer.close();
		} catch (IOException e) {
			System.err.println(Thread.currentThread().getName()
					+ ": Error saving the config file");
			throw new JmcException("error saving the config file", e);
		}
	}

	
	
	/**
	 * Browse definition for all exporters and executes them
	 * 
	 * @throws JmcException
	 */
	public void exportManagedConfig(UserInterfaceSession interfaceSession) throws JmcException {
		List list = definitionDoc.selectNodes("//exporter");

		for (Iterator iter = list.iterator(); iter.hasNext();) {
			Element elementDef = (Element) iter.next();
			ExporterInterface exporter = ExporterProducer
					.getExporter(elementDef);
			exporter.export(interfaceSession);
//			TODO FIX ME prefereably all sessions/stdout
		}
	}

	public void finalize() {
		configuration = null;
	}

	public static String listPathToString(List path) {
		String output = "";
		for (Iterator i = path.iterator(); i.hasNext();) {
			String el = (String) i.next();
			output += "/" + el;
		}
		if (output == "")
			output = "/";
		return output;
	}
}
